/**
 * 游戏流程：
 * 1.发牌(发牌之后客户端会接收到一个数组，数组里面有三个用户的牌，数组的最后一位数字表示谁先出牌);
 * 2.出牌流程：
 *      a.当一个用户选择要出的牌之后，调用方法出牌检测，看用户出得牌是否合法，不合法就选择合法的牌出
 *      b.用户出了合法的牌之后客户端直接把用户出的牌从手牌中去掉，相应的桌子上应该出现用户所出的牌
 *      c.下一个用户对比手上的牌能不能要的起桌子上的牌，要的起必须出牌
 *      d.循环
 * 3.回合结束：某个玩家手中的牌(手牌数组的长度==0)为0张的时候，该玩家获胜，回合结束
 *
 *  colour:花色，code:牌面的值，num:用于对比花色的大小（暂时用不到），toNumber:这张牌真实的大小
 * 下面为一位用户的手牌(例)：
 *[
 *
 * { colour: 'fangkuai', code: '3', num: 33, toNumber: 3 },
 * { colour: 'meihua', code: '3', num: 23, toNumber: 3 },
 * { colour: 'hongtao', code: '3', num: 13, toNumber: 3 },
 * { colour: 'fangkuai', code: '4', num: 34, toNumber: 4 },
 * { colour: 'hongtao', code: '4', num: 14, toNumber: 4 },
 * { colour: 'heitao', code: '6', num: 46, toNumber: 6 },
 * { colour: 'meihua', code: '6', num: 26, toNumber: 6 },
 * { colour: 'hongtao', code: '6', num: 16, toNumber: 6 },
 * { colour: 'meihua', code: '7', num: 27, toNumber: 7 },
 * { colour: 'heitao', code: '8', num: 48, toNumber: 8 },
 * { colour: 'meihua', code: '9', num: 29, toNumber: 9 },
 * { colour: 'hongtao', code: '10', num: 110, toNumber: 10 },
 * { colour: 'heitao', code: 'J', num: 411, toNumber: 11 },
 * { colour: 'meihua', code: 'Q', num: 212, toNumber: 12 },
 * { colour: 'hongtao', code: 'Q', num: 112, toNumber: 12 },
 * { colour: 'heitao', code: 'A', num: 414, toNumber: 14 }
 * ]
 * 
 */


//TODO  ----------------------------------------------------------------
//TODO  |注意：客户端出的牌这个数组必须根据字段：toNumber排序，之后再传递给服务端|
//TODO  -----------------------------------------------------------------


//TODO 1.客户端调用发牌方法:dealer()
//TODO 发牌之后客户端会接收到一个数组，数组里面有三个用户的牌，数组的最后一位数字表示谁先出牌

//TODO 2.客户端判断谁先出牌，第一个出牌者准备出牌

//TODO 3.出牌检测，调用出牌检测方法 cardsDetails(user_cards);返回一个集合==>{扑克牌的类型，说明，此次出牌的数量，牌面最小的值}
//TODO 客户端判断字段'poket'是否为undefined,为是否为undefined表示不能这么出牌
//TODO 正常的牌==>{ poket: 'AABBCC', explain: '连对', number: 6, poketNumber: 4 }
//TODO 非法的牌==>{ number: 2, poketNumber: 0 }

//TODO (这里其实还有一步，客户端判断玩家是否还有手牌，如果有跳转第4步，如果没有游戏结束，)
//TODO 3.1 有玩家手中的牌出完了，游戏结束
//TODO 调用方法


//TODO 4.桌面上的牌，调用方法：table_cards(user_cards)（客户端出牌的时候调用此方法，用于把出的牌放桌子上）
//TODO ==>[[桌面的牌],{桌子上牌的大小--数字类型,桌子上牌的类型--字符串,桌子上一共有几张牌--数字类型,备注--字符串}]

//TODO 5.下家出牌
//TODO 检测下家手上的所有牌能不能要的起桌子上的牌
//TODO 参数说明：桌子上牌的类型，桌子上的牌,桌子上牌面的大小，用户手上的所有牌
//TODO 调用方法：pvp(old_card_type, old_cards, old_card_size, user_cards)
//TODO ==>true//要得起
//TODO ==>false//要不起

//TODO 跳转第3步




//TODO ------------------------------------------------------------------------

//TODO 所有的牌
let initial_Poker = [
    // 黑桃
    {colour: 'heitao', code: '3', num: 43, toNumber: 3},
    {colour: 'heitao', code: '4', num: 44, toNumber: 4},
    {colour: 'heitao', code: '5', num: 45, toNumber: 5},
    {colour: 'heitao', code: '6', num: 46, toNumber: 6},
    {colour: 'heitao', code: '7', num: 47, toNumber: 7},
    {colour: 'heitao', code: '8', num: 48, toNumber: 8},
    {colour: 'heitao', code: '9', num: 49, toNumber: 9},
    {colour: 'heitao', code: '10', num: 410, toNumber: 10},
    {colour: 'heitao', code: 'J', num: 411, toNumber: 11},
    {colour: 'heitao', code: 'Q', num: 412, toNumber: 12},
    {colour: 'heitao', code: 'K', num: 413, toNumber: 13},
    {colour: 'heitao', code: 'A', num: 414, toNumber: 14},
    {colour: 'heitao', code: '2', num: 415, toNumber: 15},
    //方块
    {colour: 'fangkuai', code: '3', num: 33, toNumber: 3},
    {colour: 'fangkuai', code: '4', num: 34, toNumber: 4},
    {colour: 'fangkuai', code: '5', num: 35, toNumber: 5},
    {colour: 'fangkuai', code: '6', num: 36, toNumber: 6},
    {colour: 'fangkuai', code: '7', num: 37, toNumber: 7},
    {colour: 'fangkuai', code: '8', num: 38, toNumber: 8},
    {colour: 'fangkuai', code: '9', num: 39, toNumber: 9},
    {colour: 'fangkuai', code: '10', num: 310, toNumber: 10},
    {colour: 'fangkuai', code: 'J', num: 311, toNumber: 11},
    {colour: 'fangkuai', code: 'Q', num: 312, toNumber: 12},
    {colour: 'fangkuai', code: 'K', num: 313, toNumber: 13},
    {colour: 'fangkuai', code: 'A', num: 314, toNumber: 14},
    {colour: 'fangkuai', code: '2', num: 315, toNumber: 15},
    //梅花
    {colour: 'meihua', code: '3', num: 23, toNumber: 3},
    {colour: 'meihua', code: '4', num: 24, toNumber: 4},
    {colour: 'meihua', code: '5', num: 25, toNumber: 5},
    {colour: 'meihua', code: '6', num: 26, toNumber: 6},
    {colour: 'meihua', code: '7', num: 27, toNumber: 7},
    {colour: 'meihua', code: '8', num: 28, toNumber: 8},
    {colour: 'meihua', code: '9', num: 29, toNumber: 9},
    {colour: 'meihua', code: '10', num: 210, toNumber: 10},
    {colour: 'meihua', code: 'J', num: 211, toNumber: 11},
    {colour: 'meihua', code: 'Q', num: 212, toNumber: 12},
    {colour: 'meihua', code: 'K', num: 213, toNumber: 13},
    {colour: 'meihua', code: 'A', num: 214, toNumber: 14},
    {colour: 'meihua', code: '2', num: 215, toNumber: 15},
    //红桃
    {colour: 'hongtao', code: '3', num: 13, toNumber: 3},
    {colour: 'hongtao', code: '4', num: 14, toNumber: 4},
    {colour: 'hongtao', code: '5', num: 15, toNumber: 5},
    {colour: 'hongtao', code: '6', num: 16, toNumber: 6},
    {colour: 'hongtao', code: '7', num: 17, toNumber: 7},
    {colour: 'hongtao', code: '8', num: 18, toNumber: 8},
    {colour: 'hongtao', code: '9', num: 19, toNumber: 9},
    {colour: 'hongtao', code: '10', num: 110, toNumber: 10},
    {colour: 'hongtao', code: 'J', num: 111, toNumber: 11},
    {colour: 'hongtao', code: 'Q', num: 112, toNumber: 12},
    {colour: 'hongtao', code: 'K', num: 113, toNumber: 13},
    {colour: 'hongtao', code: 'A', num: 114, toNumber: 14},
    {colour: 'hongtao', code: '2', num: 115, toNumber: 15}
];
//TODO ------------------------发牌--------------------------------

//TODO 初始化牌（这里需要随机抽出3张2一张A)==>返回一个处理好的卡组
async function filter_system(ALL_CARDS) {
    let second = await filter([415, 315, 215, 115], 3);//随机抽出3张2
    let first = await filter([414, 314, 214, 114], 1);//随机抽出1张A
    second.push(first[0]);
    let newCards = ALL_CARDS.filter(item => !second.includes(item.num));//牌堆抽出指定的四张牌
    let promise = new Promise((resolve, reject) => {
        resolve(newCards);
    }).catch(err => {
        reject(err);
    });
    return promise;

}

//TODO 发牌方法 (同一个卡组所有卡牌，需要多少张牌)==>返回某一个用户抽到的牌
async function filter(ALL_CARDS, CARDS_NUMBER) {
    let newCards = [];
    let pick = function () {
        let index = Math.ceil((ALL_CARDS.length * Math.random())) - 1;
        return ALL_CARDS.splice(index, 1);
    };
    for (let i = 0; i < CARDS_NUMBER; i++) {
        newCards.push(pick()[0]);
    }
    let promise = new Promise((resolve, reject) => {
        resolve(newCards);
    }).catch(err => {
        reject(err);
    });
    return promise;
}

// TODO 游戏开始--每个用户获得16张排好序的手牌==>返回[[用户1的手牌]，[用户2的手牌]，[用户3的牌],number]  注意数组的最后以为数字表示谁先出牌
async function dealer() {
    let start_Poker = await filter_system(initial_Poker);//初始化牌堆
    let user1 = await filter(start_Poker, 16);//每个用户随机拿16张牌;
    let user2 = await filter(start_Poker, 16);//每个用户随机拿16张牌;
    let user3 = await filter(start_Poker, 16);//每个用户随机拿16张牌;
    user1 = await cards_sort(user1);//用户1手牌排序
    console.log(user1);
    user2 = await cards_sort(user2);//用户2手牌排序
    // console.log(user2);
    user3 = await cards_sort(user3);//用户3手牌排序
    // console.log(user3);
    let all_user_cards=[user1,user2,user3];
    let who_first_play=0;

    //TODO 谁手上有黑桃3，判断谁先出牌

    for(let i=0;i<all_user_cards.length;i++){
        for(let j=0;j<all_user_cards[i].length;j++){
            // console.log(poketJson[i]);
            if(all_user_cards[i][j].colour=='heitao'&&all_user_cards[i][j].code=='3'){
                if(i==0){
                    console.log('玩家1先出牌');
                    who_first_play=0;
                }else if(i==1){
                    console.log('玩家2先出牌');
                    who_first_play=1;
                }else if(i==2){
                    console.log('玩家3先出牌');
                    who_first_play=2;
                }else{
                    console.log('服务端出错了！！！！！！！！');

                }
                break;
            }
        }
    }

    let promise = new Promise((resolve, reject) => {
        resolve([user1, user2, user3,who_first_play]);
    }).catch(err => {
        reject(err);
    });
    return promise;


}

//TODO 每个用户抓到的牌 排序
async function cards_sort(user_cards) {
    function compare(property) {
        return function (user_cards, b) {
            let value1 = user_cards[property];
            let value2 = b[property];
            return value1 - value2;
        }
    }

    user_cards.sort(compare('toNumber'));
    let promise = new Promise((resolve, reject) => {
        resolve(user_cards);
    }).catch(err => {
        reject(err);
    });
    return promise;

}

//TODO -----------------------游戏规则---------------------------------------

//TODO 牌面检测，返回==>此牌的类型，牌的长度，以及牌的大小
async function cardsDetails(user_cards) {
    let cards = {};
    switch (user_cards.length) {
        case 1://TODO 只有单牌
            cards['poket'] = 'A';
            cards['explain'] = '单牌';
            break;
        case 2://TODO 可能是对子
            if (user_cards[0].toNumber == user_cards[1].toNumber) {
                cards['poket'] = 'AA';
                cards['explain'] = '对子';
            } else {
                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
            }
            break;
        case 3://TODO 三条 或者 特殊炸弹
            if (user_cards[0].toNumber == user_cards[1].toNumber && user_cards[0].toNumber == user_cards[2].toNumber) {
                if (user_cards[0].code == 'A') {
                    cards['poket'] = 'AAA_1';
                    cards['explain'] = '跑得快最大的炸弹';
                } else {
                    cards['poket'] = 'AAA';
                    cards['explain'] = '三条';
                }
            } else {
                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
            }
            break;
        case 4://TODO 炸弹或者3带一
            let ISok = true;
            for (let i = 1; i < user_cards.length; i++) {
                if (user_cards[0].toNumber != user_cards[i].toNumber) {
                    ISok = false;//TODO ISOK等于false表示不是炸弹
                    break;

                }
            }
            if (ISok) {
                cards['poket'] = 'AAAA';
                cards['explain'] = '普通炸弹';
            } else {//TODO 判断是否为三带一
                if (user_cards[0].toNumber == user_cards[1].toNumber && user_cards[0].toNumber == user_cards[2].toNumber) {
                    cards['poket'] = 'AAAB';
                    cards['explain'] = '三带一';
                } else {
                    if (user_cards[1].toNumber == user_cards[2].toNumber && user_cards[1].toNumber == user_cards[3].toNumber) {
                        cards['poket'] = 'AAAB';
                        cards['explain'] = '三带一';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                }
            }
            break;
        case 6:
            //TODO 四带二       AAAABB AABBBB ABCCCC ABBBBC
            //TODO 两个三条     AAABBB CCCDDD
            //TODO 顺子        ABCDEF
            //TODO 连对        AABBCC
            if (user_cards[0].toNumber + 1 == user_cards[3].toNumber) {//TODO 两个三条才有这种结果
                if (user_cards[0].toNumber == user_cards[1].toNumber && user_cards[0].toNumber == user_cards[2].toNumber) {
                    if (user_cards[3].toNumber == user_cards[4].toNumber && user_cards[3].toNumber == user_cards[5].toNumber) {
                        cards['poket'] = 'AAABBB';
                        cards['explain'] = '两个三条';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                } else {
                    //TODO 连对
                    let is_shunzi = true;
                    for (let i = 0; i < user_cards.length; i++) {
                        if (i % 2 == 1) {
                            if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber) {
                                is_shunzi = false;
                                break;
                            }
                        }
                        if (i % 2 == 0 && i != 0) {
                            if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber + 1) {
                                is_shunzi = false;
                                break;
                            }
                        }

                    }
                    if (is_shunzi) {
                        cards['poket'] = 'AABBCC';
                        cards['explain'] = '连对';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                }
            } else {
                //TODO 判断是不是顺子
                let shunzi = true;
                for (let i = 0; i < user_cards.length; i++) {
                    if (i == user_cards.length - 1) {
                        break;
                    } else {
                        if ((user_cards[i].toNumber + 1) != user_cards[i + 1].toNumber) {
                            shunzi = false;//TODO 不是顺子
                        }
                    }
                }
                if (shunzi) {
                    cards['poket'] = 'ABCDE';
                    cards['explain'] = '顺子';
                } else {
                    //TODO 判断是不是4带2
                    if (user_cards[0].toNumber == user_cards[3].toNumber) {
                        cards['poket'] = 'AAAABB';
                        cards['explain'] = '四带二';
                    } else if (user_cards[1].toNumber == user_cards[4].toNumber) {
                        cards['poket'] = 'AAAABB';
                        cards['explain'] = '四带二';
                    } else if (user_cards[2].toNumber == user_cards[5].toNumber) {
                        cards['poket'] = 'AAAABB';
                        cards['explain'] = '四带二';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                }
            }
            break;
        case 8:
            //TODO 顺子            ABCDEFGH
            //TODO 两个三条带两张牌  ABCCCDDD   ABBBCCCD  AAABBBCD
            //TODO 连对            AABBCCDD
            //TODO 先判断是不是顺子
            let ISOK1 = true;
            for (let i = 0; i < user_cards.length; i++) {
                if (i == user_cards.length - 1) {
                    break;
                } else {
                    if ((user_cards[i].toNumber + 1) != user_cards[i + 1].toNumber) {
                        ISOK1 = false;//TODO 不是顺子
                    }
                }
            }
            if (ISOK1) {
                cards['poket'] = 'ABCDE';
                cards['explain'] = '顺子';
            } else {
                //TODO 三条的判断
                if (user_cards[0].toNumber == user_cards[2].toNumber && user_cards[3].toNumber == user_cards[5].toNumber) {
                    if (user_cards[0].toNumber + 1 == user_cards[3].toNumber) {
                        cards['poket'] = 'AAABBBCD';
                        cards['explain'] = '两个三条';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }

                } else if (user_cards[1].toNumber == user_cards[3].toNumber && user_cards[4].toNumber == user_cards[6].toNumber) {
                    if (user_cards[1].toNumber + 1 == user_cards[4].toNumber) {
                        cards['poket'] = 'AAABBBCD';
                        cards['explain'] = '两个三条';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                } else if (user_cards[2].toNumber == user_cards[4].toNumber && user_cards[5].toNumber == user_cards[7].toNumber) {
                    if (user_cards[2].toNumber + 1 == user_cards[5].toNumber) {
                        cards['poket'] = 'AAABBBCD';
                        cards['explain'] = '两个三条';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                    //TODO 判断是不是连对
                } else {
                    let is_shunzi = true;
                    for (let i = 0; i < user_cards.length; i++) {
                        if (i % 2 == 1) {
                            if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber) {
                                is_shunzi = false;
                                break;
                            }
                        }
                        if (i % 2 == 0 && i != 0) {
                            if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber + 1) {
                                is_shunzi = false;
                                break;
                            }
                        }

                    }
                    if (is_shunzi) {
                        cards['poket'] = 'AABBCC';
                        cards['explain'] = '连对';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }

                }
            }


            break;
        case 12:
            //TODO 顺子 345678910JQKA
            //TODO 超级三带一 AAABBBCCCDEF  ABBBCCCDDDEF ABCCCDDDEEEF ABCDDDEEEFFF
            //TODO 四个三条
            //TODO 连对
            //TODO 先判断是不是顺子
            let ISOK2 = true;
            for (let i = 0; i < user_cards.length; i++) {
                if (i == user_cards.length - 1) {
                    break;
                } else {
                    if ((user_cards[i].toNumber + 1) != user_cards[i + 1].toNumber) {
                        ISOK2 = false;//TODO 不是顺子
                    }
                }
            }
            if (ISOK2) {
                cards['poket'] = 'ABCDE';
                cards['explain'] = '顺子';
            } else {
                //TODO 情况1： AAA BBB CCC DEF
                if (user_cards[0].toNumber == user_cards[1].toNumber && user_cards[0].toNumber == user_cards[2].toNumber) {//TODO AAA
                    if (user_cards[3].toNumber == user_cards[4].toNumber && user_cards[3].toNumber == user_cards[5].toNumber) {//TODO AAABBB
                        if (user_cards[6].toNumber == user_cards[7].toNumber && user_cards[6].toNumber == user_cards[8].toNumber) {//TODO AAABBBCCC
                            if (user_cards[0].toNumber + 1 == user_cards[3].toNumber && user_cards[0].toNumber + 2 == user_cards[6].toNumber) {//TODO AAABBBCCCDEF
                                if (user_cards[9].toNumber == user_cards[10].toNumber && user_cards[9].toNumber == user_cards[11].toNumber) {
                                    if (user_cards[8].toNumber + 1 == user_cards[9].toNumber) {//TODO AAABBBCCCDDD
                                        cards['poket'] = 'AAABBBCCCDDD';
                                        cards['explain'] = '4个三条';
                                    } else {
                                        cards['poket'] = 'AAABBBCCCDEF';
                                        cards['explain'] = '三个三条';
                                    }
                                } else {
                                    cards['poket'] = 'AAABBBCCCDEF';
                                    cards['explain'] = '三个三条';
                                }
                            } else {
                                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                            }
                        } else {
                            console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                        }
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                    //TODO 情况2： ABBBCCCDDDEF
                } else if (user_cards[1].toNumber == user_cards[2].toNumber && user_cards[1].toNumber == user_cards[3].toNumber) {
                    if (user_cards[4].toNumber == user_cards[5].toNumber && user_cards[4].toNumber == user_cards[6].toNumber) {//TODO AAABBB
                        if (user_cards[7].toNumber == user_cards[8].toNumber && user_cards[7].toNumber == user_cards[9].toNumber) {//TODO AAABBBCCC
                            if (user_cards[1].toNumber + 1 == user_cards[4].toNumber && user_cards[1].toNumber + 2 == user_cards[7].toNumber) {
                                cards['poket'] = 'AAABBBCCCDEF';
                                cards['explain'] = '三个三条';
                            } else {
                                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                            }
                        } else {
                            console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                        }
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                } else if (user_cards[2].toNumber == user_cards[3].toNumber && user_cards[2].toNumber == user_cards[4].toNumber) {//TODO 情况3： ABCCCDDDEEEF
                    if (user_cards[5].toNumber == user_cards[6].toNumber && user_cards[5].toNumber == user_cards[7].toNumber) {//TODO AAABBB
                        if (user_cards[8].toNumber == user_cards[9].toNumber && user_cards[8].toNumber == user_cards[10].toNumber) {//TODO AAABBBCCC
                            if (user_cards[2].toNumber + 1 == user_cards[5].toNumber && user_cards[2].toNumber + 2 == user_cards[8].toNumber) {
                                cards['poket'] = 'AAABBBCCCDEF';
                                cards['explain'] = '三个三条';
                            } else {
                                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                            }
                        } else {
                            console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                        }
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }

                } else if (user_cards[3].toNumber == user_cards[4].toNumber && user_cards[3].toNumber == user_cards[5].toNumber) {//TODO 情况4： ABCDDDEEEFFF
                    if (user_cards[6].toNumber == user_cards[7].toNumber && user_cards[6].toNumber == user_cards[8].toNumber) {//TODO AAABBB
                        if (user_cards[9].toNumber == user_cards[10].toNumber && user_cards[9].toNumber == user_cards[11].toNumber) {//TODO AAABBBCCC
                            if (user_cards[3].toNumber + 1 == user_cards[6].toNumber && user_cards[3].toNumber + 2 == user_cards[9].toNumber) {
                                cards['poket'] = 'AAABBBCCCDEF';
                                cards['explain'] = '三个三条';
                            } else {
                                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                            }
                        } else {
                            console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                        }
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                    //TODO 判断是不是连对
                }
                else {
                    let is_shunzi = true;
                    for (let i = 0; i < user_cards.length; i++) {
                        if (i % 2 == 1) {
                            if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber) {
                                is_shunzi = false;
                                break;
                            }
                        }
                        if (i % 2 == 0 && i != 0) {
                            if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber + 1) {
                                is_shunzi = false;
                                break;
                            }
                        }
                    }
                    if (is_shunzi) {
                        cards['poket'] = 'AABBCC';
                        cards['explain'] = '连对';
                    } else {
                        console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                    }
                }
            }


            break;
        default:
            //TODO 连对
            let isContinue = false;
            if (user_cards.length > 5 && user_cards.length < 17) {
                let is_shunzi = true;
                for (let i = 0; i < user_cards.length; i++) {
                    if (i % 2 == 1) {
                        if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber) {
                            is_shunzi = false;
                            break;
                        }
                    }
                    if (i % 2 == 0 && i != 0) {
                        if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber + 1) {
                            is_shunzi = false;
                            break;
                        }
                    }

                }
                if (is_shunzi) {
                    cards['poket'] = 'AABBCC';
                    cards['explain'] = '连对';
                    break;
                } else {
                    isContinue = true;
                    console.log('不是连对');
                }
            } else {
                isContinue = true;
                console.log('不是连对');

            }
            //TODO 顺子
            if (user_cards.length > 4 && user_cards.length < 13) {

                let ISOK = true;
                for (let i = 0; i < user_cards.length; i++) {
                    if (i == user_cards.length - 1) {
                        break;
                    } else {
                        if ((user_cards[i].toNumber + 1) != user_cards[i + 1].toNumber) {
                            ISOK = false;//TODO 不是顺子
                        }
                    }
                }
                if (ISOK) {
                    cards['poket'] = 'ABCDE';
                    cards['explain'] = '顺子';
                } else {
                    isContinue = true;
                    console.log('不是顺子');
                }
            } else {
                isContinue = true;
                console.log('不是顺子');

            }
            //TODO 飞机
            let isFeiji = true;
            if (user_cards.length > 6 && user_cards.length < 16) {
                if (user_cards.length % 3 == 0) {
                    for (let i = 0; i < user_cards.length; i++) {
                        if (i % 3 == 0) {
                            if (i != 0) {
                                if (user_cards[i].toNumber != user_cards[(i - 1)].toNumber + 1) {
                                    isFeiji = false
                                }
                            }
                            if (i != user_cards.length) {
                                if (user_cards[i].toNumber != user_cards[(i + 2)].toNumber) {
                                    isFeiji = false
                                }
                            }
                        }
                    }
                } else {
                    console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
                }
            } else {
                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
            }
            if (isFeiji) {
                if (user_cards.length == 9) {
                    cards['poket'] = 'AAABBBCCC';
                } else if (user_cards.length == 12) {
                    cards['poket'] = 'AAABBBCCCDDD';
                } else if (user_cards.length == 15) {
                    cards['poket'] = 'AAABBBCCCDDDEEE';
                } else {
                    cards['poket'] = 'AAABBB';
                }
                cards['explain'] = '飞机';
            } else {
                console.log('警告：玩家出了' + user_cards.length + '张牌，但不能这么出牌!')
            }

            break;


    }
    cards['number'] = user_cards.length;
    let poketNumber;
    poketNumber = await count(cards, user_cards);//TODO 计算牌面的值 用于比较大小
    cards['poketNumber'] = poketNumber;
    console.log(cards);
    let promise = new Promise((resolve, reject) => {
        resolve(cards);
    }).catch(err => {
        reject(err);
    });
    return promise;
}

//TODO 计算牌的面值,返回==>牌面的值（Number）
//（牌的类型，需要判断的牌数组）
async function count(cards, array) {
    let poketNumber = 0;
    switch (cards['poket']) {
        case 'A'://TODO 单牌
            poketNumber = array[0].toNumber;
            break;
        case 'AA'://TODO 对子
            poketNumber = array[0].toNumber;
            break;
        case 'AAA'://TODO 三条
            poketNumber = array[0].toNumber;
            break;
        case 'AAA_1'://TODO 炸弹
            poketNumber = 99999;
            break;
        case 'AAAA'://TODO 炸弹
            poketNumber = array[0].toNumber;
            break;
        case 'AAAB'://TODO 三带一 (ABBB||AAAB)两种情况
            for (let i = 0; i < array.length; i++) {
                if (i != array.length - 1) {
                    if (array[i].toNumber == array[i + 1].toNumber) {//TODO 判断第一个数是否等于第二个数，等于的话就是AAAB 反之ABBB
                        poketNumber = array[i].toNumber;
                        break;
                    } else {
                        poketNumber = array[i + 1].toNumber;
                        break;
                    }
                } else {
                    break;
                }
            }
            break;
        case 'AAAABB'://TODO 四带二
            for (let i = 0; i < array.length; i++) {
                if (i != array.length - 1) {
                    if (array[i].toNumber == array[i + 1].toNumber && array[i].toNumber == array[i + 3]) {//TODO 判断第一个数是否等于第2个数&&等于第4个数，等于就是AAAABC
                        poketNumber = array[i].toNumber;
                        break;
                    } else if (array[i + 1].toNumber == array[i + 2].toNumber && array[i + 1].toNumber == array[i + 4]) {//TODO 判断是不是ABBBBC
                        poketNumber = array[i + 1].toNumber;
                        break
                    } else {
                        poketNumber = array[i + 2].toNumber;
                        break
                    }
                } else {
                    break;
                }
            }
            break;
        case 'ABCDE'://TODO 顺子
            poketNumber = array[0].toNumber;
            break;
        case 'AABBCC'://TODO 连对
            poketNumber = array[0].toNumber;
            break;
        case 'AAABBB'://TODO 飞机
            console.log('这个地方要主要看清楚是几张牌的飞机');
            poketNumber = array[0].toNumber;
            break;
        case 'AAABBBCD'://TODO 带了牌的飞机 八张牌特有  可能出现 AAABBBCD ABBBCCCD ABCCCDDD
            for (let i = 0; i < array.length; i++) {
                if (array[i].toNumber == array[i + 1].toNumber && array[i].toNumber == array[i + 2].toNumber) {//TODO 判断是否为 AAABBBCD
                    poketNumber = array[i].toNumber;
                    break;
                } else if (array[i + 1].toNumber == array[i + 2].toNumber && array[i + 1].toNumber == array[i + 3].toNumber) {//TODO 判断是否为 ABBBCCCD
                    poketNumber = array[i + 1].toNumber;
                    break
                } else { //TODO 前者都不是那就是ABCCCDDD
                    poketNumber = array[i + 2].toNumber;
                    break
                }
            }
            console.log(poketNumber);
            break;
        case 'AAABBBCCCDEF'://TODO 飞机(三个三条带三张牌) AAABBBCCCDEF ABBBCCCDDDEF ABCCCDDDEEEF ABCDDDEEEFFF
            console.log('飞机对比');
            for (let i = 0; i < array.length; i++) {
                if (array[i].toNumber == array[i + 3].toNumber - 1 && array[i].toNumber == array[i + 6].toNumber - 2) {//TODO 判断是否为AAABBBCCCDEF
                    poketNumber = array[i].toNumber;
                    break;
                } else if (array[i + 1].toNumber == array[i + 4].toNumber - 1 && array[i + 1].toNumber == array[i + 7].toNumber - 2) {//TODO 判断是否为AAABBBCCCDEF
                    poketNumber = array[i + 1].toNumber;
                    break;
                } else if (array[i + 2].toNumber == array[i + 5].toNumber - 1 && array[i + 2].toNumber == array[i + 8].toNumber - 2) {//TODO 判断是否为AAABBBCCCDEF
                    poketNumber = array[i + 2].toNumber;
                    break;
                } else {//TODO 判断是否为AAABBBCCCDEF
                    poketNumber = array[i + 3].toNumber;
                    break;
                }
            }
            console.log(poketNumber);
            break;
        case 'AAABBBCCCDDD'://TODO 飞机
            poketNumber = array[0].toNumber;
            break;
        case 'AAABBBCCC'://TODO 飞机
            poketNumber = array[0].toNumber;
            break;
    }
    let promise = new Promise((resolve, reject) => {
        resolve(poketNumber);
    }).catch(err => {
        reject(err);
    });
    return promise;


}

//TODO 玩家选择出得牌能不能要的起桌子上的牌==>返回（true：要得起||false：要不起）
//(桌子上牌的类型，玩家牌的类型，桌子上的牌，玩家出得牌,桌子上牌的大小，玩家出牌的大小)
async function poket_rule(old_card_type, user_card_type, old_cards, user_cards, old_card_size, user_card_size) {
    let isPass = false;//默认要不起，不能出牌
    switch (old_card_type) {
        case 'A'://TODO 单牌
            if (user_card_type == 'A') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AA'://TODO 对子
            if (user_card_type == 'AA') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAA'://TODO 三条
            if (user_card_type == 'AAA') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAA_1'://TODO 炸弹
            isPass = true;
            break;
        case 'AAAA'://TODO 炸弹
            if (user_card_type == 'AAAA') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            }
            break;
        case 'AAAB'://TODO 三带一
            if (user_card_type == 'AAAB') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAAABB'://TODO 四带二
            if (user_card_type == 'AAAABB') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'ABCDE'://TODO 顺子  这个地方有坑！注意顺子的长度
            if (user_card_type == 'ABCDE' && old_cards.length == user_cards.length) {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;
            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AABBCC'://TODO 连对
            if (user_card_type == 'AABBCC' && old_cards.length == user_cards.length) {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAABBB'://TODO 飞机
            if (user_card_type == 'AAABBB' && old_cards.length == user_cards.length) {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAABBBCD'://TODO 飞机
            if (user_card_type == 'AAABBBCD') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAABBBCCCDEF'://TODO 飞机
            if (user_card_type == 'AAABBBCCCDEF') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
        case 'AAABBBCCCDDD'://TODO 飞机
            if (user_card_type == 'AAABBBCCCDDD') {//TODO 类型相同对比大小
                user_card_size > old_card_size ? isPass = true : message = false;

            } else if (user_card_type == 'AAA_1') {//TODO 超级炸弹
                isPass = true
            } else if (user_card_type == 'AAAA') {//TODO 炸弹
                isPass = true
            }
            break;
    }
    let promise = new Promise((resolve, reject) => {
        resolve(isPass);
    }).catch(err => {
        reject(err);
    });
    return promise;

}

//TODO 桌子上的牌 客户端每调用一次则更新桌面上的牌
async function table_cards(user_cards) {
    //记录桌子上的牌
    let old_cards=user_cards;
    let new_old_cards=await cardsDetails(user_cards);//TODO 正常的牌==>{ poket: 'AABBCC', explain: '连对', number: 6, poketNumber: 4 }
    let cards={};
    //桌子上牌的大小
    cards.old_card_size=new_old_cards.poketNumber;
    //桌子上牌的类型
    cards.old_card_type=new_old_cards.poket;
    //桌子上有几张牌
    cards.old_card_number=new_old_cards.number;
    //桌子上牌的备注
    cards.old_card_explain=new_old_cards.explain;
    //TODO 组合桌子上牌的信息，返回给客户端
    //TODO 参数：[[桌子上的牌],{桌子上牌的大小--数字类型，桌子上牌的类型--字符串，桌子上一共有几张牌--数字类型，备注--字符串}]
    let table_cards=[old_cards,cards];

    let promise = new Promise((resolve, reject) => {
        resolve(table_cards);
    }).catch(err => {
        reject(err);
    });
    return promise;

    
}

//TODO ——————————————跑得快特殊玩法，要得起必须出牌——————————————————————————
//TODO 检测玩家手上的所有牌，看能否要的起桌子上的牌==>返回（true：玩家必须出牌||false：玩家要不起）
// 需要参数，，桌子上牌的类型，桌子上的牌,桌子上牌面的大小，用户手上的所有牌
async function pvp(old_card_type, old_cards, old_card_size, user_cards) {
    let isPass = false;
    let newCards = [];//要得起的，同类型的牌
    let newBomb = [];//炸弹
    switch (old_card_type) {
        case 'A'://TODO 单牌
            for (let i = 0; i < user_cards.length; i++) {
                if (user_cards[i].toNumber > old_card_size) {
                    isPass = true;
                    break;
                }
            }
            break;
        case 'AA'://TODO 对子
            newCards = await pve(user_cards, old_card_type, 2);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }

            break;
        case 'AAA'://TODO 三条
            newCards = await pve(user_cards, old_card_type, 3);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAA_1'://TODO 炸弹
            newCards = await pve(user_cards, old_card_type, 3);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            break;
        case 'AAAA'://TODO 炸弹
            newCards = await pve(user_cards, old_card_type, 4);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAAB'://TODO 三带一
            newCards = await pve(user_cards, old_card_type, 4);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAAABB'://TODO 四带二
            newCards = await pve(user_cards, old_card_type, 6);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'ABCDE'://TODO 顺子  这个地方有坑！注意顺子的长度
            newCards = await pve(user_cards, old_card_type, 5);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AABBCC'://TODO 连对
            newCards = await pve(user_cards, old_card_type, 6);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAABBB'://TODO 飞机
            newCards = await pve(user_cards, old_card_type, 6);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAABBBCD'://TODO 飞机
            newCards = await pve(user_cards, old_card_type, 8);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAABBBCCC'://TODO 飞机
            newCards = await pve(user_cards, old_card_type, 9);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAABBBCCCDEF'://TODO 飞机
            newCards = await pve(user_cards, old_card_type, 12);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
        case 'AAABBBCCCDDD'://TODO 飞机
            newCards = await pve(user_cards, old_card_type, 12);
            if (newCards.length > 0) {
                for (let i = 0; i < newCards.length; i++) {
                    if (newCards[i].toNumber > old_card_size) {
                        isPass = true;
                        break;
                    }
                }
            }
            newBomb = await pve_bomb(user_cards, old_card_type);
            if (newBomb.length > 0) {
                isPass = true;
            }
            break;
    }
    let promise = new Promise((resolve, reject) => {
        resolve(isPass);
    }).catch(err => {
        reject(err);
    });
    console.log(isPass);
    return promise;
}

//TODO 检测玩家手上的所有牌，看有没有指定牌的类型==>返回 指定类型的牌的第一张牌
//参数：用户手上的牌，指定牌的类型，多少张
async function pve(user_cards, old_card_type, number) {
    //TODO 3,4,4,5,5,6,6,6,7,7,7,8,9,9,10,12
    let array = [];
    switch (old_card_type) {
        case 'A'://TODO 单牌
            //TODO 单牌不用判断
            break;
        case 'AA'://TODO 对子
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 1) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber) {
                        array.push(user_cards[i])
                    }
                } else {
                    break;
                }
            }
            break;
        case 'AAA'://TODO 三条
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 2) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber) {
                        array.push(user_cards[i]);
                    }
                } else {
                    break;
                }
            }
            break;
        case 'AAA_1'://TODO 炸弹
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 2) {
                    if (user_cards[i].code == 'A' && user_cards[i + 1].code == 'A' && user_cards[i + 2].code == 'A') {
                        array.push(user_cards[i]);
                    }
                }
            }
            break;
        case 'AAAA'://TODO 炸弹
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 3) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber) {
                        array.push(user_cards[i]);
                    }
                }
            }
            break;
        case 'AAAB'://TODO 三带一
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 2) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber && user_cards.length > 3) {
                        array.push(user_cards[i]);
                    }
                } else {
                    break;
                }
            }
            break;
        case 'AAAABB'://TODO 四带二
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 3) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber && user_cards.length > 5) {
                        array.push(user_cards[i]);
                    }
                }

            }
            break;
        case 'ABCDE'://TODO 顺子  这个地方有坑！注意顺子的长度
            user_cards = await groupBy(user_cards, 'code');//TODO 去除重复看有没有顺子
            console.log(user_cards)
            if (user_cards.length < 5 && user_cards.length < number) {
                break;
            } else {
                let a = 0;
                for (let i = 0; i < user_cards.length; i++) {
                    if (i < user_cards.length - 1) {
                        if (user_cards[i].toNumber == user_cards[i + 1].toNumber - 1) {
                            a += 1;
                            if (a == number - 1) {//TODO 有number张顺子的时候自动回到第二张牌开始判断
                                array.push(user_cards[i + 1 - a]);
                                i = i + 1 - a;
                                a = 0;
                            }
                        } else {
                            a = 0;
                        }
                    }
                }
            }
            break;
        case 'AABBCC'://TODO 连对
            number = number / 2;
            let newArray = [];
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 1) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber) {
                        newArray.push(user_cards[i])
                    }
                }

            }
            if (newArray.length > 0) {
                newArray = await groupBy(newArray, 'code');//TODO 先去除重复，再寻找顺子
                let a = 0;
                for (let i = 0; i < newArray.length; i++) {
                    if (i < newArray.length - 1) {
                        if (newArray[i].toNumber == newArray[i + 1].toNumber - 1) {
                            a += 1;
                            if (a == number - 1) {//TODO 有number张顺子的时候自动回到第二张牌开始判断
                                array.push(newArray[i + 1 - a]);
                                i = i + 1 - a;
                                a = 0;
                            }
                        } else {
                            a = 0;
                        }
                    }
                }


            }


            break;
        case 'AAABBB'://TODO 飞机
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 5) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber) {
                        if (user_cards[i + 3].toNumber == user_cards[i + 4].toNumber && user_cards[i + 3].toNumber == user_cards[i + 5].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber - 1) {
                            array.push(user_cards[i]);
                        }
                    }
                }

            }
            break;
        case 'AAABBBCD'://TODO 飞机

            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 5) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber) {
                        if (user_cards[i + 3].toNumber == user_cards[i + 4].toNumber && user_cards[i + 3].toNumber == user_cards[i + 5].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber - 1) {
                            if (user_cards.length > 7) {
                                array.push(user_cards[i]);
                            }
                        }
                    }
                }

            }

            break;
        case 'AAABBBCCCDEF'://TODO 飞机
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 8) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber) {
                        if (user_cards[i + 3].toNumber == user_cards[i + 4].toNumber && user_cards[i + 3].toNumber == user_cards[i + 5].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber - 1) {
                            if (user_cards[i + 6].toNumber == user_cards[i + 7].toNumber && user_cards[i + 6].toNumber == user_cards[i + 8].toNumber && user_cards[i + 3].toNumber == user_cards[i + 6].toNumber - 1) {
                                if (user_cards.length > 11) {
                                    array.push(user_cards[i]);
                                }
                            }
                        }
                    }
                }
            }
            break;
        case 'AAABBBCCCDDD'://TODO 飞机
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 12) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber) {
                        if (user_cards[i + 3].toNumber == user_cards[i + 4].toNumber && user_cards[i + 3].toNumber == user_cards[i + 5].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber - 1) {
                            if (user_cards[i + 6].toNumber == user_cards[i + 7].toNumber && user_cards[i + 6].toNumber == user_cards[i + 8].toNumber && user_cards[i + 3].toNumber == user_cards[i + 6].toNumber - 1) {
                                if (user_cards[i + 9].toNumber == user_cards[i + 10].toNumber && user_cards[i + 9].toNumber == user_cards[i + 11].toNumber && user_cards[i + 6].toNumber == user_cards[i + 9].toNumber - 1) {
                                    if (user_cards.length > 11) {
                                        array.push(user_cards[i]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
        case 'AAABBBCCCDDDEEE'://TODO 飞机
            for (let i = 0; i < user_cards.length; i++) {
                if (i < user_cards.length - 15) {
                    if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 2].toNumber) {
                        if (user_cards[i + 3].toNumber == user_cards[i + 4].toNumber && user_cards[i + 3].toNumber == user_cards[i + 5].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber - 1) {
                            if (user_cards[i + 6].toNumber == user_cards[i + 7].toNumber && user_cards[i + 6].toNumber == user_cards[i + 8].toNumber && user_cards[i + 3].toNumber == user_cards[i + 6].toNumber - 1) {
                                if (user_cards[i + 9].toNumber == user_cards[i + 10].toNumber && user_cards[i + 9].toNumber == user_cards[i + 11].toNumber && user_cards[i + 6].toNumber == user_cards[i + 9].toNumber - 1) {
                                    if (user_cards[i + 12].toNumber == user_cards[i + 13].toNumber && user_cards[i + 12].toNumber == user_cards[i + 14].toNumber && user_cards[i + 9].toNumber == user_cards[i + 12].toNumber - 1) {
                                        if (user_cards.length > 14) {
                                            array.push(user_cards[i]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            break;
    }
    if (array.length > 0) {
        array = await groupBy(array, 'code');
    }
    let promise = new Promise((resolve, reject) => {
        resolve(array);
    }).catch(err => {
        reject(err);
    });
    return promise;


}

//TODO 特殊地方，只要有炸弹或者超级炸弹直接扔到数组里面去；==>返回一个炸弹数组
//（用户手上的牌，桌子上牌的类型）
async function pve_bomb(user_cards, old_card_type) {
    let bomb = [];
    if (old_card_type != 'AAAA') {//TODO 只要用户出得不是炸弹，都可以炸
        for (let i = 0; i < user_cards.length; i++) {
            if (i < user_cards.length - 3) {
                if (user_cards[i].toNumber == user_cards[i + 1].toNumber && user_cards[i].toNumber == user_cards[i + 3].toNumber) {
                    bomb.push(user_cards[i]);
                }
            }
            if (old_card_type != 'AAA_1') {
                if (i < user_cards.length - 2) {
                    if (user_cards[i].code == 'A' && user_cards[i + 1].code == 'A' && user_cards[i + 2].code == 'A') {
                        bomb.push(user_cards[i]);
                    }
                }
            }

        }
    } else {

        for (let i = 0; i < user_cards.length - 2; i++) {
            if (user_cards[i].code == 'A' && user_cards[i + 1].code == 'A' && user_cards[i + 2].code == 'A') {
                bomb.push(user_cards[i]);
            }
        }


    }
    console.log(bomb);
    let promise = new Promise((resolve, reject) => {
        resolve(bomb);
    }).catch(err => {
        reject(err);
    });
    return promise;

}

//TODO 游戏结束
//参数：
function game_over() {
    console.log('游戏结束');
    console.log('保存数据到数据库ing……')
}




//TODO ----------------------------工具-----------------------------------
//TODO 数组去重

/**
 * 去除重复---接受一个需要去重的数组，接受一个数组对象里面用来去重的元素
 * 根据数组中的对象的重复的元素进行去重
 * 例如：[{name:'x',num:1},{name:'xx',num:2},{name:'xx',num:3},{name:'xx',num:4}]
 * groupBy(array,'name');
 * ==>[{name:'x',num:1},{name:'xx',num:2}]
 */
function groupBy(arr, name) {
    let hash = {};
    return arr.reduce(function (item, next) {
        hash[next[name]] ? '' : hash[next[name]] = true && item.push(next);
        return item;
    }, []);
}





